#include <iostream>
#include <string>

#include <sys/types.h>
#include <signal.h>
#include <unistd.h>

int count = 0;

void catchSig(int signo)
{
    std::cout << "获取一个信号编号，编号是:" << signo << " count:" << count << std::endl;
    // exit(1);
    // alarm(1);
}

// 3.硬件异常产生信号
// a 除0异常
void test1()
{
    // 信号产生，不一定由用户显示发送。有可能由操作系统自动产生

    int a = 10;
    a /= 0; // 为什么除0 会终止进程？ 当前进程会收到来自OS的信号
}

// b 空指针引用
void test2()
{
    while (true)
    {
        std::cout << "我正在执行代码" << std::endl;
        sleep(1);
        int *p = nullptr; // 解引用空指针，发生段错误
        *p = 1;
    }
}

// 4. 软件条件产生信号
// 软件条件 -- "闹钟"其实就是软件实现的, pipe写端关闭，读端退出也是软件产生的
void test3()
{
    signal(SIGALRM, catchSig);

    // 可以累计1秒，我们计算机可以将数据累计多少次
    alarm(1);
    while (true)
    {
        count++;
    }
}

// 核心转储
void test4()
{
    int a[5];
    std::cout << "访问a[10]" << std::endl;

    while (true)
    {
        a[10] = 10; // 越界访问
        std::cout << "访问a[10000]" << std::endl;
        a[10000] = 10000; // 越界访问
        std::cout << a[10] << std::endl;
    }
}

// 6. 自定义所有信号行为，进程是否可以退出？
void test5()
{
    for (int signo = 1; signo <= 31; signo++)
    {
        signal(signo, catchSig);
    }

    while (true)
    {
        std::cout << "我在运行 pid:" << getpid() << std ::endl;
        sleep(1);
    }
}

int main()
{
    // 3.硬件异常产生信号
    //  signal(SIGFPE, catchSig);
    //  signal(SIGSEGV,catchSig);
    //  test1();
    //  test2();

    // 4. 软件条件产生信号
    // test3();

    // 5. 核心转储，core与term
    // test4();

    // 6. 自定义所有信号行为，进程是否可以退出？
    //test5();
    return 0;
}
